<?php

class Service_Presentation_Xml_Node
{
    const DEFAULT_NODE_NAME = 'item';

    protected $_name = self::DEFAULT_NODE_NAME;

    protected $_attrs = array();

    protected $_childs = array();

    protected $_content = null;

    public function __construct($name = self::DEFAULT_NODE_NAME,
            $attrs = array(), $childs = array())
    {
        $this->setChilds($childs);
        $this->setAttributes($attrs);
        $this->setName($name);
    }

    public function setChilds($childs)
    {
        $this->_childs = (null === $childs ? array() : $childs);
        return $this->_childs;
    }

    public function getChilds()
    {
        return $data;
    }

    public function setAttributes($attrs)
    {
        $this->_attrs = (null === $attrs ? array() : $attrs);
        return $this;
    }

    public function getAttributes()
    {
        return $this->_attrs;
    }

    public function setName($name)
    {
        $this->_name = (string) $name;
        return $this;
    }

    public function getName()
    {
        return $this->_name;
    }

    public function setAttribute($name, $value)
    {
        $this->_attrs[$name] = $value;
        return $this;
    }

    public function getAttribute($name)
    {
        return $this->_attrs[$name];
    }

    public function removeAttribute($name)
    {
        if (isset($this->_attrs[$name])) {
            unset($this->_attrs[$name]);
        }
        return $this;
    }

    public function addChild($child)
    {
        $this->_childs[] = $child;
        return $this;
    }

    public function toString()
    {
        return $this->__toString();
    }

    public function __toString()
    {
        // if childs are iterable
        if (is_array($this->_childs) || $this->_childs instanceof Iterator) {

            $content = '';
            
            // itarate over childs
            foreach ($this->_childs as $key => $part) {

                // if child is not XML node
                if (!($part instanceof self)) {

                    // determine node name
                    if (is_numeric($key)) {
                        $name = self::DEFAULT_NODE_NAME;
                    } else {
                        $name = $key;
                    }

                    // convert child to node
                    $part = new self($name, array(), $part);
                    
                }

                // append child
                $content .= $part;
            }

        } else {
            
            if (!empty($this->_childs) && !is_numeric($this->_childs)) {
                $content = '<![CDATA['
                         . str_replace(']]>', ']]]]><![CDATA[>', $this->_childs)
                         . ']]>';
            } else {
                $content = $this->_childs;
            }
        }

        // return node string
        return "<{$this->_name}{$this->_attrsToString()}>{$content}</{$this->_name}>";
    }

    protected function _attrsToString()
    {
        $str = '';

        if (is_array($this->_attrs)) {
            foreach ($this->_attrs as $name => $value) {
                $value = htmlspecialchars($value);
                $str .= " {$name}=\"{$value}\"";
            }
        }

        return $str;
    }
}
